// 工具库
const _ = require("lodash");
// 路径
const path = require("path");
// 文件系统
const fs = require("fs");

// 使用 ESM 模块
const esm = require("esm");
// 读取模块
const requireModule = esm(module);

// 读取所有值
const { readAllValues } = requireModule(
  "../awakened-potential/helpers/readAllValues.js"
);

const checkAccuracy = requireModule("./utils/checkAccuracy.js");

// 读取历史数据
const allValues = readAllValues("m")
// .slice(0, 500);

// 所有号码
const allNumbers = Array.from({ length: 49 }, (_, i) => i + 1).map((n) =>
  n < 10 ? `0${n}` : `${n}`
);

// 窗口模式
const useWindow = true;
// 窗口大小
// const windowSize = 70;
const windowSize = 39;

// 预测结果
const predictResults = [];

// 遍历每一期开奖数据，从第2期开始预测（前面没有足够数据无法判断）
allValues.forEach((item, index) => {
  // 构造参考历史窗口：窗口模式用滑动窗口，否则用从头到当前
  const temp = useWindow
    ? allValues.slice(Math.max(0, index - windowSize), index)
    : allValues.slice(0, index);

  // 没有历史参考则跳过（如第1期）
  if (!temp.length) return;

  // 初始化每个号码的统计信息
  const stats = {};
  allNumbers.forEach((num) => {
    stats[num] = {
      appearCount: 0, // 出现次数
      lastAppearDistance: Infinity, // 距离当前期最近一次出现的间隔
    };
  });

  // 遍历参考期，记录每个号码的出现次数和最近一次出现位置
  temp.forEach((entry, i) => {
    const number = entry.number;
    if (stats[number]) {
      stats[number].appearCount++;
      stats[number].lastAppearDistance = temp.length - i;
    }
  });

  // 为每个号码计算综合评分（热度 + 冷却结合）
  const scoreMap = {};
  for (const num of allNumbers) {
    const { appearCount, lastAppearDistance } = stats[num];

    // 你可以根据实际效果微调以下权重：
    const score =
      appearCount * 2 + // 热号分：出现次数越多越好
      Math.min(lastAppearDistance, 10); // 冷号加分：未出现越久越高（ capped at 10）

    scoreMap[num] = score;
  }

  // 按得分降序排序，取前32个号码
  const finalSelected = Object.entries(scoreMap)
    .sort((a, b) => b[1] - a[1]) // 按评分降序排序
    .map(([num]) => num)
    .slice(0, 32); // 选出前 32 个号码

  // 输出结果
  // todo cyan: 检查temp数据
//   console.log(`${item.time} 预测号码:`, finalSelected);
//   console.log(`${item.time} 开奖号码:`, item.number);
//   console.log(`${item.time} 预测结果:`, checkAccuracy(finalSelected, item.number));

  // 记录预测结果
  predictResults.push(checkAccuracy(finalSelected, item.number));
});



// 计算统计结果 predictResults
// 准确率，最大连续错误次数之类的

// 计算准确率
const total = predictResults.length;
const correct = predictResults.filter(x => x === 1).length;
const accuracy = total > 0 ? (correct / total * 100).toFixed(2) : 0;

// 计算最大连续错误次数
let maxWrongStreak = 0;
let currentStreak = 0;
predictResults.forEach(res => {
  if (res === 0) {
    currentStreak++;
    if (currentStreak > maxWrongStreak) {
      maxWrongStreak = currentStreak;
    }
  } else {
    currentStreak = 0;
  }
});

// 输出统计结果
console.log(`预测总数: ${total}`);
console.log(`命中次数: ${correct}`);
console.log(`准确率: ${accuracy}%`);
console.log(`最大连续错误次数: ${maxWrongStreak}`);

